package by.bsuir.chess.vo
{
	import by.bsuir.chess.enums.Color;
	import by.bsuir.chess.events.PiecePositionEvent;
	import by.bsuir.chess.validators.BeatValidator;
	import by.bsuir.chess.validators.PiecePositionValidator;

	import flash.events.EventDispatcher;

	import flash.geom.Point;

	public class Piece extends EventDispatcher
	{
		public static const PAWN : int = 0;
		public static const ROOK : int = 1;
		public static const BISHOP : int = 2;
		public static const KNIGHT : int = 4;
		public static const QUEEN : int = 8;
		public static const KING : int = 16;

		private var _position : Point;
		private var _color : int;
		private var _type : int;

		public function Piece(type : int, position : Point, color : int)
		{
			this.type = type;
			this.position = position;
			this.color = color;
		}

		public function get position() : Point
		{
			return _position;
		}

		public function set position(value : Point) : void
		{
			var event : PiecePositionEvent = new PiecePositionEvent(_position.clone(), value);
			_position = value;
			dispatchEvent(event);
		}

		public function get type() : int
		{
			return _type;
		}

		public function set type(value : int) : void
		{
			_type = value;
		}

		public function get color() : int
		{
			return _color;
		}

		public function set color(value : int) : void
		{
			_color = value;
		}

		//first get moves according to rules, then cut possible moves if something is on the way
		public function getMoves() : Positions
		{
			var res : Positions = new Positions();
			var p : Point;
			switch(type)
			{
				case Piece.PAWN:
					if(color == Color.WHITE)
					{
						if(position.y == 2)
						{
							p = new Point(position.x, position.y + 2);
							if(PiecePositionValidator.validate(this, p))
								res.push(p);
						}
						p = new Point(position.x, position.y + 1);
						if(PiecePositionValidator.validate(this, p))
							res.push(p);
					}
					else
					if(color == Color.BLACK)
					{
						if(position.y == 7)
						{
							p = new Point(position.x, position.y - 2);
							if(PiecePositionValidator.validate(this, p))
								res.push(p);
						}
						p = new Point(position.x, position.y - 1);
						if(PiecePositionValidator.validate(this, p))
							res.push(p);
					}
					break;

				case Piece.KNIGHT:
					p = new Point(position.x + 2, position.y + 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x + 1, position.y + 2);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 2, position.y - 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 1, position.y - 2);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 2, position.y + 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 1, position.y + 2);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x + 2, position.y - 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x + 1, position.y - 2);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					break;
				case Piece.BISHOP:
					p = new Point(position.x + 1, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y + 1);
					}
					p = new Point(position.x + 1, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y - 1);
					}
					p = new Point(position.x - 1, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y + 1);
					}
					p = new Point(position.x - 1, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y - 1);
					}
					break;

				case Piece.ROOK:
					p = new Point(position.x + 1, position.y);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y);
					}
					p = new Point(position.x - 1, position.y);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y);
					}
					p = new Point(position.x, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x, p.y + 1);
					}
					p = new Point(position.x, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x, p.y - 1);
					}
					break;
				case Piece.QUEEN:
					p = new Point(position.x + 1, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y + 1);
					}
					p = new Point(position.x + 1, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y - 1);
					}
					p = new Point(position.x - 1, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y + 1);
					}
					p = new Point(position.x - 1, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y - 1);
					}
					p = new Point(position.x + 1, position.y);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x + 1, p.y);
					}
					p = new Point(position.x - 1, position.y);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x - 1, p.y);
					}
					p = new Point(position.x, position.y + 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x, p.y + 1);
					}
					p = new Point(position.x, position.y - 1);
					while(PiecePositionValidator.validate(this, p))
					{
						res.push(p);
						if(BeatValidator.validate(this, p))
							break;
						p = new Point(p.x, p.y - 1);
					}
					break;
				case Piece.KING:
					p = new Point(position.x + 1, position.y + 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x + 1, position.y);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x + 1, position.y - 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 1, position.y + 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 1, position.y);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x - 1, position.y - 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x, position.y + 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					p = new Point(position.x, position.y - 1);
					if(PiecePositionValidator.validate(this, p))
						res.push(p);
					break;

			}
			return res;
		}
	}
}